#include "msg_assem.h"

//0x8001 platform common rpy
INT32 msgHead_assem(MSG_HD *pIn, UINT8 *pOut)
{
	if(pIn == NULL || pOut == NULL)
		return -1;
	pOut[0] = 0x7e;
	(*(UINT16 *)(&pOut[1]))= htons(pIn->id);
	(*(UINT16 *)(&pOut[3]))= htons(pIn->attr);
	memcpy(&pOut[5], pIn->phone, sizeof(pIn->phone));
	(*(UINT16 *)(&pOut[11])) = htons(pIn->seqNum);

	if(pIn->attr & MSG_ENC_FLAG)
	{
		(*(UINT16 *)(&pOut[13])) = htons(pIn->enc.total);
		(*(UINT16 *)(&pOut[15])) = htons(pIn->enc.num);

		return MSG_HEAD_EXIST_ENC_LEN;
	}
	return MSG_HEAD_INEXIST_ENC_LEN;
}

INT32 msgTail_assem(UINT8 *pTail, UINT8 crc)
{
	if(pTail == NULL)
		return -1;
	pTail[0] = crc;
	pTail[1] = 0x7e;

	return 0;
}

INT32 send_package(UINT8 *pMsg, UINT8 len, INT32 sfd)
{
	UINT16 ix;
	INT32 dataLen = 0;
	UINT8 *pSend = NULL, *pTmp = NULL;

	if(pMsg[0] != 0x7e || pMsg[len-1] != 0x7e)
		return -1;
	pSend = (UINT8 *)malloc(2*len);

	if(pSend == NULL)
	{
		free(pSend);
		perror("malloc().");
		return -1;
	}
	memset(pSend, 0,(UINT32)(2*len));

	pTmp = pSend;
	pSend[0] = 0x7e;
	for(ix = 1; ix < len-1; ix++)
	{
		if(pMsg[ix] == 0x7e)
		{
			*(++pSend) = 0x7d;
			*(++pSend) = 0x02;
		}
		else if(pMsg[ix] == 0x7d)
		{
			*(++pSend) = 0x7d;
			*(++pSend) = 0x01;
		}
		else
		{
			*(++pSend) = pMsg[ix];
		}
	}
	*(++pSend) = 0x7e;
	dataLen = pSend - pTmp + 1;
	for(ix = 0; ix < dataLen; ix++){
		fprintf(stdout, "%02x ", pTmp[ix]);
		//change
		fprintf(stderr, "%02x ", pTmp[ix]);
	}
	putchar('\n');
	fputc('\n', stderr);

	return send_ack_msg(sfd, pTmp, dataLen);
}

//0x8001
INT32 platform_common_ack(UINT16 ackSeqNum, UINT16 ackId, UINT8 result, INT32 sfd)
{
	UINT8 msg[30] = {0};
	INT32 headLen;
	UINT8 crc = 0;
	MSG_HD msgHd = {0};

	msgHd.id = 0x8001;
	msgHd.attr = sizeof(ackSeqNum) + sizeof(ackId) + sizeof(result);
	memcpy(msgHd.phone, g_installArgs.terminalTel, sizeof(msgHd.phone));//terminal phone
	msgHd.seqNum = g_installArgs.seqNum++;	

	//msg head
	headLen = msgHead_assem(&msgHd, msg);
	if(headLen == -1)
		return headLen;
	//msg body
	(*(UINT16 *)(&msg[headLen])) = htons(ackSeqNum);
	(*(UINT16 *)(&msg[headLen+2])) = htons(ackId);
	msg[headLen+4] = result;

	crc = count_crc(msg, headLen+5);
	//msg tail
	if(msgTail_assem(&msg[headLen+5], crc) == -1)
		return -1;
	
	return send_package(msg, headLen+7, sfd);
}

//0x8100 term reg rpy
INT32 term_register_ack(UINT16 ackSeqNum, INT8 result, UINT8 *aKey, INT32 sfd)//0 have akey
{
	UINT8 msg[100] = {0};
	INT32 headLen, keyLen;
	UINT8 crc = 0;
	MSG_HD msgHd = {0};

	keyLen = strlen((char *)aKey);
	msgHd.id = 0x8100;
	msgHd.attr = sizeof(ackSeqNum) + sizeof(result) + keyLen;
	memcpy(msgHd.phone, g_installArgs.terminalTel, sizeof(msgHd.phone));//terminal phone
	msgHd.seqNum = ++g_installArgs.seqNum;	

	//msg head
	headLen = msgHead_assem(&msgHd, msg);
	if(headLen == -1)
		return headLen;
	//msg body
	(*(UINT16 *)(&msg[headLen])) = htons(ackSeqNum);
	msg[headLen+2] = result;
	memcpy(&msg[headLen+3], aKey, keyLen);

	//change:call the wrong function
	crc = count_crc(msg, headLen+3+keyLen);
	//msg tail
	if(msgTail_assem(&msg[headLen+3+keyLen], crc) == -1)
		return -1;
	
	return send_package(msg, headLen+5+keyLen, sfd);
}

//INT32 platf_msg_assem(UINT8 *pbody, INT32 datLen, UINT16 msgId, INT32 tsfd)
INT32 platf_msg_assem(UINT8 *pbody, INT32 datLen, PASS_MSG *pass, INT32 tsfd)//sfd is terminal
{
	UINT8 msg[1042*4] = {0};
	INT32 headLen;
	UINT8 msgNum, crc = 0;
	MSG_HD msgHd = {0};
	INT8 telep[13] = "0";

	msgHd.id = pass->msgId;
	strncat(telep, pass->sim, strlen((const char *)pass->sim));
	simStr_convert_hex(telep, msgHd.phone);
//	memcpy(msgHd.phone, p_installArgs.terminalTel, sizeof(msgHd.phone));//platform phone

	if(datLen > MAX_PKG_BODY_LEN)
	{
		msgHd.attr |= MSG_ENC_FLAG;		

		if(datLen % MAX_PKG_BODY_LEN)
		{
			msgHd.enc.total = datLen/MAX_PKG_BODY_LEN + 1;
		}
		else{
			msgHd.enc.total = datLen/MAX_PKG_BODY_LEN;
		}
		for(msgNum = 0; msgNum < msgHd.enc.total; msgNum++)
		{
			msgHd.enc.num++;
			msgHd.attr |= MAX_PKG_BODY_LEN;
			msgHd.seqNum = g_installArgs.seqNum++;

			//msg head
			headLen = msgHead_assem(&msgHd, msg);
			if(headLen == -1)
				return headLen;
			//msg body
			memcpy(&msg[headLen], pbody, (size_t)MAX_PKG_BODY_LEN);

			crc = count_crc(msg, headLen+MAX_PKG_BODY_LEN);
			//msg tail
			if(msgTail_assem(&msg[headLen+MAX_PKG_BODY_LEN], crc) == -1)
				return -1;
			send_package(msg, headLen+MAX_PKG_BODY_LEN+2, tsfd);
			pbody += MAX_PKG_BODY_LEN;
			memset(msg, 0, sizeof(msg));			
			msgHd.attr &= 0xfc00;
		}
	}
	else{
		msgHd.attr = datLen;
		msgHd.seqNum = g_installArgs.seqNum++;
		//msg head
		headLen = msgHead_assem(&msgHd, msg);
		if(headLen == -1)
			return headLen;
		//msg body
		memcpy(&msg[headLen], pbody, msgHd.attr);

		crc = count_crc(msg, headLen+msgHd.attr);
		//msg tail
		if(msgTail_assem(&msg[headLen+msgHd.attr], crc) == -1)
			return -1;

		return send_package(msg, headLen+msgHd.attr+2, tsfd);
	}
	return 0;
}

